package com.vivebest.utils.chc.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xml.internal.utils.StringToIntTable;
import com.vivebest.utils.chc.domain.ConsulHealthCheck;
import com.vivebest.utils.chc.domain.vo.ConsulHealthCheckResVo;
import com.vivebest.utils.chc.domain.ConsulHealth;
import com.vivebest.utils.common.constant.enums.CmdEnums;
import com.vivebest.utils.common.service.CmdTemplateTransformService;
import com.vivebest.utils.common.utils.CmdUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * consul 健康检查
 * </p>
 *
 * @author zsk
 * @date 2020/8/5 下午7:58
 */
@Service
@Log4j2
public class ConsulHealthCheckService {

    @Autowired
    CmdTemplateTransformService cmdTemplateTransformService;

    /**
     * @return 服务健康注册信息
     */
    public ConsulHealthCheckResVo fetchHealthCheckInfo() {
        log.debug("获取服务健康注册信息开始");
        ConsulHealthCheckResVo consulHealthCheckResVo = new ConsulHealthCheckResVo();
        try {
            String cmdForGetAllServices = "kubectl exec -f /opt/app/file/banking-consul-service.yaml -- consul catalog services";
            String cmdForGetServiceHealth = "kubectl exec -f /opt/app/file/banking-consul-service.yaml -- consul watch -type=checks -service={0}";
            String result = CmdUtils.processCmd(cmdForGetAllServices).getResult();

            List<String> serviceNameList = Arrays.asList(result.split("\n"));
            List<ConsulHealthCheck> consulHealthChecks = new ArrayList<>();

            consulHealthCheckResVo.setDescriptionServiceNum("服务应总数量：21  ---" + "服务实总数量：" + serviceNameList.size());
            log.debug("服务应总数量：21  ---" + "服务实总数量：" + serviceNameList.size());
            serviceNameList.forEach(curServiceName -> {
                String response = "";
                String curCmdForGetServiceHealth = cmdForGetServiceHealth;
                curCmdForGetServiceHealth = curCmdForGetServiceHealth.replace("{0}", curServiceName);
                try {
                    response = CmdUtils.processCmd(curCmdForGetServiceHealth).getResult();
                    consulHealthChecks.add(consulHealthCheck(response,curServiceName));
                } catch (IOException e) {
                    log.error("{}服务健康检测请求超时！", curServiceName);
                    e.printStackTrace();
                }
            });

            consulHealthCheckResVo.setConsulHealthChecks(consulHealthChecks);

            log.debug("获取服务健康注册信息结束");
            return consulHealthCheckResVo;
        } catch (Exception e) {
            log.error("----error-----");
            e.printStackTrace();
        }

        //请求失败
        consulHealthCheckResVo.setDescriptionServiceNum("网络波动，请稍后来访，谢谢");
        return consulHealthCheckResVo;
    }

    public static ConsulHealthCheck consulHealthCheck(String response,String serviceName){
        List<String> responses = JSONArray.parseArray(response, String.class);
        ConsulHealthCheck consulHealthCheck = new ConsulHealthCheck();
        consulHealthCheck.setServiceName(serviceName);
        log.debug("服务名称：" + serviceName);
        if (!CollectionUtils.isEmpty(responses)) {
            consulHealthCheck.setStatus(
                    responses.stream().collect(ArrayList::new, (objects, resp) -> {
                        ConsulHealth curConsulHealth = JSONObject.parseObject(resp, ConsulHealth.class);
                        objects.add(curConsulHealth.getStatus());
                        log.debug("健康状况：" + curConsulHealth.getStatus());
                    }, ArrayList::addAll)
            );
        } else {
            consulHealthCheck.setStatus(Collections.emptyList());
            log.debug("健康状况：[]");
        }
        return consulHealthCheck;
    }
}
